package com.re6g3y.game.Tile.Hexagonal;

import com.badlogic.gdx.math.Vector2;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 游戏地图
 */
public class HexagonalMap {
    //常量
    public static final float innerRadius = 20*11;//内切圆半径
    public static final float outerRadius = innerRadius/(float) Math.sqrt(3)*2;//六边形的边长
    public static final float dx=outerRadius*1.5f;
    public static final float dy=innerRadius;
    protected static final float sqrt3=(float)Math.sqrt(3);

    public final Map<Long, Object> entityMap = new ConcurrentHashMap<Long,   Object>();


    public void setEntity(Object o,Vector2 p){
        long hash=getTileIterator(p).getVal();
        setEntity(o,hash);
    }
    public void setEntity(Object o,HexagonalIterator iter) {
        long hash = iter.getVal();
        setEntity(o,hash);
    }
    public void setEntity(Object o,long hash){
//        if(entityMap.get(hash)==null){
//            synchronized (entityMap){
//                if(entityMap.get(hash)==null){
//                    entityMap.put(hash, new ConcurrentHashMap<Integer, Object>());
//                }
//            }
//        }
        entityMap.put(hash,o);
    }

    public void removeEntity(Object o,Vector2 p){
        long hash=getTileIterator(p).getVal();
        removeEntity(o,hash);
    }
    public void removeEntity(Object o,HexagonalIterator iter) {
        long hash = iter.getVal();
        removeEntity(o,hash);
    }
    public void removeEntity(Object o,long hash){
//        if(entityMap.get(hash)==null){
//            synchronized (entityMap){
//                if(entityMap.get(hash)==null){
//                    entityMap.put(hash, new ConcurrentHashMap<Integer, Object>());
//                }
//            }
//        }
        entityMap.remove(hash);
    }

//
//    /**
//     * 开始到结束，包含端点
//     * @param startRange 开始
//     * @param endRange 结束
//     * @return 全部实体
//     */
//    public Set<Object> getTileEntitysByPointAndRange(Vector2 p, int startRange, int endRange){
//        if(startRange<0)throw new IllegalArgumentException();
//        Set<Object> ans=new HashSet<Object>();
//        HexagonalIterator now=getTileIterator(p);
//
//        HexagonalIterator next=new HexagonalIterator(now);
//        if(startRange==0)ans.add(new HexagonalTile(getTileCenter(now),now.getVal()));
//        for(int i=startRange;i<=endRange;i++){
//
//            next.set(now).addX(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addY(1);
//            }
//            next.set(now).addXY(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addYZ(1);
//            }
//            next.set(now).addY(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addZ(1);
//            }
//            next.set(now).addYZ(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addZX(1);
//            }
//            next.set(now).addZ(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addX(1);
//            }
//            next.set(now).addZX(i);
//            for(int j=0;j<i;j++){
////                getTileEntitys(next);
//                ans.add(new HexagonalTile(getTileCenter(next),now.getVal()));
//                next.addXY(1);
//            }
//        }
//        return ans;
//    }
//



    /**
     * 开始到结束，包含端点
     * @param startRange 开始
     * @param endRange 结束
     * @return 全部实体
     */
    public void queryByPointAndRange(Vector2 p, QueryCallback queryCallback, int startRange, int endRange){
        HexagonalIterator now=getTileIterator(p);
        queryByPointAndRange(now,queryCallback,startRange,endRange);
    }
    /**
     * 开始到结束，包含端点
     * @param startRange 开始
     * @param endRange 结束
     * @return 全部实体
     */
    public void queryByPointAndRange(long hash, QueryCallback queryCallback, int startRange, int endRange){
        HexagonalIterator now=new HexagonalIterator(hash);
        queryByPointAndRange(now,queryCallback,startRange,endRange);
    }

    /**
     * 开始到结束，包含端点
     * @param startRange 开始
     * @param endRange 结束
     * @return 全部实体
     */
    public void queryByPointAndRange(HexagonalIterator now, QueryCallback queryCallback, int startRange, int endRange){
        if(startRange<0)throw new IllegalArgumentException();
        HexagonalIterator next=new HexagonalIterator(now);

        if(startRange==0)if(queryCallback.Callback(next))return;
        for(int i=startRange;i<=endRange;i++){

            next.set(now).addX(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addY(1);
            }
            next.set(now).addXY(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addYZ(1);
            }
            next.set(now).addY(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addZ(1);
            }
            next.set(now).addYZ(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addZX(1);
            }
            next.set(now).addZ(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addX(1);
            }
            next.set(now).addZX(i);
            for(int j=0;j<i;j++){
                if(queryCallback.Callback(next))return;
                next.addXY(1);
            }
        }
    }

    /**
     * 获取该tile全部实体
     */
    public Object  getEntities(Vector2 p) {
        return getEntities(getTileIterator(p).getVal());
    }

    public Object getEntities(HexagonalIterator iter){
        return getEntities(iter.getVal());
    }

    public Object getEntities(Long hash){
//        if(entityMap.get(hash)==null) {
//            return new HashSet<Object>();
//        }
        return entityMap.get(hash);
    }



    public Vector2 getTileCenter(Vector2 p){
        return getTileCenter(getTileIterator(p));
    }
    /**
     * 输入tile的下表获取位置
     *
     * @param x
     * @param y
     */
    private Vector2 getTileCenter(int x, int y,Vector2 target) {
        return target.set(((y) *dx), ((x * 2 + y) * dy));
    }
    /**
     * 输入tile的下表获取位置
     *
     * @param x
     * @param y
     */
    private Vector2 getTileCenter(int x, int y) {
        return new Vector2(((y) *dx), ((x * 2 + y) * dy));
    }

    /**
     * 输入tile的下表获取center位置
     *
     * @param l Long
     */
    public Vector2 getTileCenter(HexagonalIterator l) {
        return new Vector2(((l.getY()) *dx), ((l.getX() * 2 + l.getY()) * dy));
    }

    /**
     * 输入tile的下表获取center位置
     *
     * @param l Long
     */
    public Vector2 getTileCenter(HexagonalIterator l,Vector2 target) {
        return target.set(((l.getY()) *dx), ((l.getX() * 2 + l.getY()) * dy));
    }

    public HexagonalIterator getTileIterator(Vector2 p) {
//        p = Vector2.sub(p, RunTime.offsetVector);
        
        int x=(int)Math.floor(p.x/dx);
        int y=(int)Math.floor(p.y/dy);

//        list.add(new Rect(new Point2D.Double(x*dx,y*dy),new Point2D.Double(dx,dy)));

        double modx=p.x-x*dx-dx/2;
        double mody=p.y-y*dy-dy/2;

        int cellx=x;
        int celly=(int)(Math.floor((y-x)/2.0));

        if(((x^y)&1)==0){
            if(modx*sqrt3/2+mody/2>0){
                cellx++;
            }
        }else{
            if(modx*sqrt3/2-mody/2>0){
                cellx++;
            }else celly++;
        }

//        RunTime.mainDrawer.add(new Rect(getTileCenter(celly,cellx),new Vector2(10,10)));
//        return tfXY(celly,cellx);
        return new HexagonalIterator(celly,cellx);
//        if (!list.isEmpty()) list.remove(list.size() - 1);
//        list.add(new HexagonalTile(getTileIndex(celly,cellx)));
//        return null;
    }


//    List<NodeBase> list = new LinkedList<>();

    public HexagonalMap() {
//        for (int i = 0; i < 24; i++) {
//            for (int j = 0; j < 12; j++) {
//                int k=j-i/2;
////                g.drawImage(img,(int)(i*dis/Math.sqrt(1.0/3)-centerX+p.getX()),(int)(j*2*dis+i*dis-centerY+p.getY()),null);
//                list.add(new HexagonalTile(new Vector2(((i) * dx ), ((k * 2 + i) * dy))));
//            }
//        }
    }

//    public List<NodeBase> getTileNodeList() {
//        return list;
//    }

}
